package com.wj.java;

public class BinaryUtil {
    
    //十进制转二进制的除法运算
    private static void IntegerToRadix(StringBuilder result, String target, int radix) {
        if(target == null || target.length() == 0) {
            return ;
        }
        
        int len = target.length();
        
        //保存某一次的商
        StringBuilder quotientString = new StringBuilder();
        
        int index = 0;
        
        String prevChar = "";
        int indexValue = 0;//当前遍历的值，可能包含上一次遍历留下的值
        int remainder = 0;//余数
        while(index < len) {
            String currentChar = prevChar + String.valueOf(target.charAt(index ++));
            indexValue = Integer.parseInt(currentChar);

            int v = indexValue / radix;
            remainder = indexValue % radix;
            
            if(quotientString.length() > 0 || v > 0) {
                quotientString.append(v);
            }
            
            prevChar = String.valueOf(remainder);
        }
        
        result.append(remainder);

        if(quotientString.length() > 0) {
            IntegerToRadix(result, quotientString.toString(), radix);
        }
    }

    //十进制整数部分转为二进制
    public static String tenIntegerPartToBinary(String valueString) {

        String[] values = valueString.split("\\.");
        String value = valueString;
        if(values.length > 0) {
            value = values[0];
        }
        
        StringBuilder rs = new StringBuilder();
        IntegerToRadix(rs, value, 2);
        return rs.reverse().toString();
    }
    
    
    private static String mulByRadix(String value, int radix) {
        if(value == null || value.length() == 0) {
            return "";
        }
        
        int len = value.length();
        int index = len - 1;
        StringBuilder builder = new StringBuilder();
        int prevValue = 0;
        while(index >= 0) {
            char v = value.charAt(index --);
            
            int vValue = Integer.parseInt(String.valueOf(v)) * radix + prevValue;
            
            builder.append(vValue % 10);
            
            prevValue = vValue / 10;
        }
        
        if(prevValue > 0) {
            builder.append(prevValue);
        }
        
        return builder.reverse().toString();
    }
    //实际值是否为0
    private static boolean isAllZeroFloat(String v) {
        for(char c : v.toCharArray()) {
            if(c != '0') {
                return false;
            }
        }
        return true;
    }
    //十进制，小数部分转二级制
    public static String tenFloatPartToBianary(String valueString) {
        if(valueString == null || valueString.length() == 0) {
            return "";
        }
        
        String[] values = valueString.split("\\.");
        String value = valueString;
        if(values.length > 0) {
            value = values[values.length - 1];
        }
        
        int len = value.length();
        
        StringBuilder result = new StringBuilder();
        
        int precision = 8;
        while(precision -- > 0) {
            //计算乘法值
            value = mulByRadix(value, 2);

            if(value.length() > len) {
                result.append(value.substring(0, 1));
                value = value.substring(value.length() - len);
            } else {
                result.append("0");
            }
            //为0，则结束；这里其实是精度值判断，达到精度值，就返回true，会跳出
            if(isAllZeroFloat(value)) {
                break;
            }
        }
        return result.toString();
    }
    
    public static void main(String[] args) {
        String v = "1321321321.0625";
        System.out.println(tenIntegerPartToBinary(v));
        System.out.println(tenFloatPartToBianary(v));
    }
}
